package com.liehu.user.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.liehu.user.pojo.Customer;
import com.liehu.user.pojo.Employee;
import com.liehu.user.pojo.EncryptedData;
import com.liehu.user.service.CustomerService;

import util.HttpClientUtil;
import entity.PageResult;
import entity.Result;
import entity.StatusCode;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import util.JwtUtil;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/customer")
@CrossOrigin //跨域处理
@Api(value = "/customer",description = "客户")
public class CustomerController {
    @Autowired
    private CustomerService customerService;
    @Autowired
    private RedisTemplate redisTemplate; //redis
    @Autowired
    private JwtUtil jwtUtil; // JWt令牌工具类
    @Autowired
    private HttpClientUtil httpClientUtil;//http工具类




    /**
     * 查询所有
     */
    @ApiOperation(value = "查询全部回复", notes = "查询全部回复")//描述
    @GetMapping()
    public Result findAll(){
        return  new Result(true, StatusCode.OK,"查询成功！",customerService.findAll());
    }

    /**
     * 根据id查询
     */
    @ApiOperation(value = "根据id查询", notes = "根据id查询")//描述
    @GetMapping("/{id}")
    public Result findById(@PathVariable("id") String id){
        return  new Result(true, StatusCode.OK,"查询成功！",customerService.findById(id));
    }
    /**
     * 插入一条数据
     */
    @ApiOperation(value = "插入一条数据", notes = "插入一条数据,需要管理员操作")//描述
    @PostMapping()
    public Result save(@RequestBody Customer customer){
        customerService.save(customer);
        return  new Result(true, StatusCode.OK,"新增成功！");
    }

    /**
     * 根据id修改记录
     * @param customer
     * @param id
     * @return
     */
    @ApiOperation(value = "根据id修改记录", notes = "根据id修改记录，需要管理员操作")//描述
    @PutMapping("/{id}")
    public Result update(@RequestBody Customer customer,@PathVariable("id") String id){
        customer.setId(id);//给reply植入id
        customerService.update(customer);
        return  new Result(true, StatusCode.OK,"修改成功！");
    }
    /**
     * 根据id删除
     */
    @ApiOperation(value = "根据id删除", notes = "根据id删除，需要管理员操作")//描述
    @DeleteMapping("/{id}")
    public Result delete(@PathVariable("id") String id){
        customerService.deleteById(id);
        return  new Result(true, StatusCode.OK,"删除成功！");
    }

    /**
     * 分页查询
     */
    @ApiOperation(value = "分页查询", notes = "不带条件的分页查询")//描述
    @GetMapping("/{page}/{size}")
    public Result findByPage(@PathVariable("page") Integer page,@PathVariable("size") Integer size){
        Page<Customer> list = customerService.findByPage(page, size);
        return  new Result(true, StatusCode.OK,"查询成功！",new PageResult<Customer>(list.getTotal(),list.getRecords()));
    }
    /**
     * 带条件的分页查询
     */
    @ApiOperation(value = "分页查询", notes = "带条件的分页查询")//描述
    @PostMapping("/search/{page}/{size}")
    public Result findByPageSearch(@RequestBody Customer customer,@PathVariable("page") Integer page,@PathVariable("size") Integer size){
        Page<Customer> list = customerService.findByPage(customer, page, size);
        return  new Result(true, StatusCode.OK,"查询成功！",new PageResult<Customer>(list.getTotal(),list.getRecords()));
    }
    /**
     * 发送短信
     */
    @ApiOperation(value = "发送短信", notes = "发送短信")//描述
    @PostMapping("/send/{mobile}")
    public Result sendMsm(@PathVariable("mobile") String mobile){
        customerService.sendMsm(mobile);
        return new Result(true,StatusCode.OK,"发送成功！");
    }

    /**
     * 客户注册
     * @return
     * @param checkCode 验证码
     */
    @ApiOperation(value = "用户注册", notes = "用户注册")//描述
    @PostMapping("/register/{checkCode}")
    public Result register(@RequestBody Customer customer,@PathVariable("checkCode") String checkCode){
        //1.先从缓存中取出验证码，如果验证码不存在，直接返回
        String code = (String) redisTemplate.opsForValue().get("checkCode" + customer.getMobile());
        if(code==null || code.equals("")){
            return  new Result(false,StatusCode.ERROR,"请先获取验证码！");
        }
        //2.如果验证码存在，就比对验证码是否正确，如果验证码错误，直接返回。
        if(!code.equals(checkCode)){
            return  new Result(false,StatusCode.ERROR,"验证码错误！");
        }
        //3.如果验证码正确，先根据电话号码从数据库里查询，如果已经存在，则直接返回！
        if(customerService.findByMobile(customer.getMobile())!=null){
            return  new Result(false,StatusCode.ERROR,"该号码已经注册！");
        }

        //4.如果一切正常，就执行注册。
        customerService.save(customer);
        return new Result(true,StatusCode.OK,"注册成功");
    }
    /**
     * 用户登录
     */
    @ApiOperation(value = "根据密码进行登录", notes = "根据密码进行登录")//描述
    @PostMapping("/login/password")
    public Result loginByPassword(@RequestBody Customer customer){
        //1.根据电话号码和密码进行查询 --先鉴权
        customer  = customerService.loginByPassword(customer.getMobile(),customer.getPassword());
        //2.如果查询的对象为空，则提示账户密码错
        if(customer == null){
            return new Result(false,StatusCode.LOGINERROR,"用户名或密码错误");
        }
        //3.如果不为空，则执行登录 登录的同时默认角色为customer。
        String token = jwtUtil.createJWT(customer.getId(), customer.getNickName(), "customer");

        //4.一切顺利，颁发Token  -- 授权
        Map<String,Object> map = new HashMap<>();
        map.put("token",token);
        map.put("roles","customer");
        return new Result(true,StatusCode.OK,"登录成功！",map);
    }

    /**
     * 根据验证码进行登录
     * @param customer
     * @param checkCode
     * @return
     */
    @ApiOperation(value = "根据验证码进行登录", notes = "根据密码进行登录")//描述
    @PostMapping("/login/{checkCode}")
    public Result loginByCheckCode(@RequestBody Customer customer,@PathVariable("checkCode") String checkCode){
        //1.先根据电话号码查看缓存中是否存在验证码
        String code = (String) redisTemplate.opsForValue().get("checkCode" + customer.getMobile());
        if(code == null || code.equals("")){
            return  new Result(false,StatusCode.ERROR,"请先获取验证码！");
        }
        //2.如果验证码存在，则进行比较验证码是否正确
        if(!checkCode.equals(code)){
            return  new Result(false,StatusCode.ERROR,"证码错误!");
        }
        //3.如果验证码正确，就去查询该用户的信息
        customer = customerService.findByMobile(customer.getMobile());
        if(customer == null){
            return  new Result(false,StatusCode.ERROR,"该号码不存在!");
        }

        //4.用户信息无误，则进行授权，颁发token
        String token = jwtUtil.createJWT(customer.getId(), customer.getNickName(), "customer");
        Map<String,Object> map = new HashMap<>();
        map.put("token",token);
        map.put("roles","customer");
        return new Result(true,StatusCode.OK,"登录成功！",map);
    }

    /**
     * 小程序的授权登录
     * @param code
     * @return
     */
    @ApiOperation(value = "微信小程序登录", notes = "code为微信小程序wx.login()获取的临时码") //描述
    @PostMapping("/wx/login/{code}")
    public Result loginByWx(
                            @RequestBody Customer customer,
                            @PathVariable("code") String code
                            ) {
        //1.根据code来获取用户的openid和session_key
        String url = "https://api.weixin.qq.com/sns/jscode2session?";//腾讯url接口，获取session和openid
        Map<String,String> param  = new HashMap<>();
       // param.put("appid", "wxd198fc796b094da8");
        param.put("appid", "wxce23f1872435c1b2");
      //  param.put("secret", "be2587cbdcf79e743b8a02a076754775");
        param.put("secret", "4d1768dfdda3bb51a3c88386ff45470c");
        param.put("js_code",code);
        param.put("grant_type", "authorization_code");
        String session_key;
        String openId;
        //发起HTTPGET请求，用于获取openId和session_key
        try {
            String wxRes = HttpClientUtil.doGet(url, param);//携带参数发送请求并返回json对象
            JSONObject jsonObject = JSONObject.parseObject(wxRes);//转化json为键值对的数据类型
            session_key = jsonObject.get("session_key").toString();//session_key
            openId = jsonObject.get("openid").toString();//openId
        }catch (Exception e){
            return new Result(false,StatusCode.ERRORCODE,"code无效");
        }

        //根据openid查询数据库是否有当前用户，如果没有，执行注册后登录，如果有，执行直接登录
      Customer c =   customerService.findByOpenId(openId);
        String token; //token令牌
        if(c == null){
            //执行注册操作
            customer.setOpenId(openId);
            customerService.save(customer);//插入
             c =   customerService.findByOpenId(openId);//将插入的数据查询出来
            //执行授权
            token = jwtUtil.createJWT(c.getId(), c.getNickName(), "customer");
            Map<String,Object> map = new HashMap<>();
            map.put("token",token);
            map.put("roles","customer");
            redisTemplate.opsForValue().set("session_key"+c.getId(),session_key,2L, TimeUnit.DAYS);//将该session_key存入缓存
            return new Result(true,StatusCode.OK,"登录成功！",map);
        }
        //不为空，执行登录操作
        token = jwtUtil.createJWT(c.getId(), c.getNickName(), "customer");
        redisTemplate.opsForValue().set("session_key"+c.getId(),session_key,2L, TimeUnit.DAYS);//将该session_key存入缓存,时间为2天
        Map<String,Object> map = new HashMap<>();
        map.put("token",token);
        map.put("roles","customer");
        return new Result(true,StatusCode.OK,"登录成功！",map);




    }
    /**
     * 解密手机号码
     */
    @ApiOperation(value = "获取手机号码", notes = "encryptedData和iv用于获取手机号") //描述
    @PostMapping("/wx/encryptedData/mobile")
    public Result  encryptedMobile(@RequestBody EncryptedData encryptedData){
       String mobile =  customerService.encryptedMobile(encryptedData.getEncryptedData(),encryptedData.getIv());
       if(mobile == null || mobile.equals("")){
           return new Result(false,StatusCode.ERROR,"解密失败！");

       }
        return new Result(true,StatusCode.OK,"解密成功！");
    }


    /**
     * 获取当前登录的用户信息
     * @return
     */
    @ApiOperation(value = "获取当前登录的用户信息", notes = "前端通过传入当前登录的token来获取当前登录的用户信息") //描述
    @GetMapping("/getUserInfo")
    public Result getUserInfo(){
        Customer userInfo = customerService.getUserInfo();
        if(userInfo == null){
            return new Result(false,StatusCode.ERROR,"token有误！");
        }
        return new Result(true,StatusCode.OK,"获取成功！",userInfo);
    }
    /**
     * 修改当前登录客户密码
     */
    @ApiOperation(value = "修改当前登录客户密码", notes = "修改当前登录客户密码，如管理员操作，请勿调用此接口")//描述
    @PutMapping("/login/password")
    public Result updateByPassword(@RequestBody Customer customer){
        customerService.updateByPassword(customer.getPassword());
        return new Result(true,StatusCode.OK,"修改成功！");
    }








}
